package com.lw.config;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
import com.google.common.collect.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * 这里使用的都是单键分片策略
 *  * 示例分库策略是：
 *  * GoodsId<=20使用db_0库
 *  * 其余使用db_1库
 * @author LW
 * @2021/9/3 12:33
 */
@Component
public class DatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Long> {

    /**（除此，还有无key和多key的分片策略）
     * 实现SingleKeyDatabaseShardingAlgorithm单键分库算法中的三个方法
     */
    @Autowired
    private DB_1Config db_1Config;

    @Autowired
    private DB_2Config db_2Config;

    //做平等分片
    @Override
    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        Long value = shardingValue.getValue();
        if (value <= 20L) {
            return db_1Config.getDatabaseName();
        } else {
            return db_2Config.getDatabaseName();
        }
    }

    //在分片中做
    @Override
    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
        for (Long value : shardingValue.getValues()) {
            if (value <= 20L) {
                result.add(db_1Config.getDatabaseName());
            } else {
                result.add(db_2Config.getDatabaseName());
            }
        }
        return result;
    }

    //在分片之间做
    @Override
    public Collection<String> doBetweenSharding(Collection<String> availableTargetNames,
                                                ShardingValue<Long> shardingValue) {
        Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
        Range<Long> range = shardingValue.getValueRange();
        for (Long value = range.lowerEndpoint(); value <= range.upperEndpoint(); value++) {
            if (value <= 20L) {
                result.add(db_1Config.getDatabaseName());
            } else {
                result.add(db_2Config.getDatabaseName());
            }
        }
        return result;
    }
}

